/*
 * Manhattan15Puzzle.cpp
 *
 *  Created on: 18/05/2011
 *      Author: frandres
 */

#include "Manhattan15Puzzle.h"

	Manhattan15Puzzle::Manhattan15Puzzle()
	{

		int i,j;
		int goalCordinates[16][2] = {{0,0}, {0,1}, {0,2}, {0,3}, {1,0} , {1,1}, {1,2}, {1,3}, {2,0}, {2,1}, {2,2}, {2,3}, {3,0}, {3,1}, {3,2}, {3,3}};

		heuristics = (char ***)malloc(16*16*4*sizeof(char **));

		for(i = 0; i<16; i++){
			heuristics[i] = (char **)malloc(16*4*sizeof(char *));
			for(j = 0; j<16; j++)
				heuristics[i][j] = (char *)malloc(4*sizeof(char));
		}

		for(i = 0; i < 16; i++)
		{
			for(j = 0; j < 16; j++)
			{
				for(int k = 0; k < 4; k++)
				{

					int x = j/4, y = j%4;


					switch(k){
						case MOVE_UP:
							if(x-1 >= 0)
								heuristics[i][j][k] = (x > goalCordinates[i][0] ? -1 : 1);
							else
								heuristics[i][j][k] = 0;
							break;
						case MOVE_DOWN:
							if(x+1 < 4)
								heuristics[i][j][k] = (x < goalCordinates[i][0] ? -1 : 1);
							else
								heuristics[i][j][k] = 0;
							break;
						case MOVE_LEFT:
							if(y-1 >= 0)
								heuristics[i][j][k] = (y > goalCordinates[i][1] ? -1 : 1);
							else
								heuristics[i][j][k] = 0;
							break;
						case MOVE_RIGHT:
							if(y+1 < 4)
								heuristics[i][j][k] = (y < goalCordinates[i][1] ? -1 : 1);
							else
								heuristics[i][j][k] = 0;
							break;

					}

				}
			}
		}
	}

	Manhattan15Puzzle::~Manhattan15Puzzle()
	{

		for(int i = 0; i<16; i++)
		{
			for(int j = 0; j<16; j++)
				free(heuristics[i][j]);

			free(heuristics[i]);
		}

		free(heuristics);

	}

	unsigned short int Manhattan15Puzzle::initiate(int board[])
	{

		int i, h = 0;
		int goalCordinates[16][2] = {{0,0}, {0,1}, {0,2}, {0,3}, {1,0} , {1,1}, {1,2}, {1,3}, {2,0}, {2,1}, {2,2}, {2,3}, {3,0}, {3,1}, {3,2}, {3,3}};

		for(i=0; i<16; i++)
		{
			if(board[i] != 0){
				int x = board[i]/4, y = board[i]%4;
				h += ABS(x-goalCordinates[i][0]) + ABS(y-goalCordinates[i][1]);
			}

		}

		return h;

	}

	unsigned short int  Manhattan15Puzzle::calculateHeuristic(int number, int position, int movement, int oldH)
	{
		return oldH + heuristics[number][position][movement];
	}

